package progen.experimenter;

import progen.kernel.error.Error;

/**
 * Clase que fabrica las distintas condiciones de los bucles, en función 
 * de los parámetros que lo definen.
 * 
 * @author jirsis
 * @since 2.0
 */
public abstract class LoopCondition {
	
	/**
	 * Tolerancia para la cual se considerará que se cumple la condición de parada.
	 */
	protected static final double TOLERANCE=0.0000000001;
	
	/**
	 * Comprueba si el valor actual sigue cumpliendo la condición o no.
	 * 
	 * @param current Valor actual a comprobar.
	 * @param end Valor final del bucle.
	 * @return <code>true</code> si ha llegado a la condición de fin y <code>false</code> en 
	 * caso contrario.
	 */
	public abstract boolean end(double current, double end);
	
	/**
	 * Método de generación de una instancia de un bucle. En función de si el <i>comienzo</i> es mayor
	 * o menor que el <i>final</i>, devolverá una instancia de un bucle que cumple
	 * la condición &gt;= o &lt;=. También comprueba si con el incremento proporcionado
	 * se puede conseguir o no la condición de parada.
	 * 
	 * @param start Valor inicial del bucle.
	 * @param end Valor final del bucle.
	 * @param increment Incremento en cada paso del bucle.
	 * @return Una instancia que comprobará la condición de parada.
	 * @throws IllegalArgumentException, en caso de el incremento no esté definido correctamente.
	 */
	public static LoopCondition makeInstance(double start, double end, double increment){
		LoopCondition condition=null;
		
		if(increment==0){
			throw new IllegalArgumentException(Error.get(30));
		}
		
		if(start<end){
			condition=new LessEqualThanLoopCondition(increment);
		}else{
			condition=new GratherEqualThanLoopCondition(increment);
		}
		
		
		return condition;
	}
}
